package com.javastudy.liuhouse.lambda.stream;

import org.junit.Test;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class OutPutStream {
    @Test
    public void testOutPutStream01() {
        Stream<Integer> s1 = Stream.generate(new NatualSupplier());
        Stream<Integer> s2 = s1.map(n -> n * n);
        Stream<Integer> s3 = s2.map(n -> n - 1);
        Stream<Integer> s4 = s3.limit(10);
        Integer reduce = s4.reduce(0, (acc, n) -> acc + n);
        System.out.println(reduce);
//        System.out.println(s3);
//        System.out.println(s1);
    }

    @Test
    public void testList(){
        //reduce只是一种聚合操作,如果我们希望吧Stream的元素保存到集合
        //例如List，因为List元素是确定的java对象,因此，把Stream变为List不是一个转换操作
        //而是一个聚合操作,他会强制Stream 输出每个元素
        Stream<String> stream = Stream.of("Apple", "", null, "Pear", "  ", "Orange");
        List<String> list = stream.filter(s -> s != null && !s.isBlank()).collect(Collectors.toList());
        System.out.println(list);
    }


    //输出为数组
    @Test
    public void testArray(){
        //把Stream的元素输出为数组和输出为List类似,我们只需要调用
        List<String> list = List.of("Apple" , "Banana" , "Orange");
        String[] array = list.stream().toArray(String[]::new);
        System.out.println(array);
    }

    //输出为Map
    @Test
    public void testMap(){
        //如果我们要把Stream的元素收集到Map中，就稍微麻烦一点。因为对于每个元素，添加到Map时需要key和value，因此，我们要指定两个映射函数，分别把元素映射为key和value
        Stream<String> stream = Stream.of("Appl:Apple", "MSFT:Microsft");
        Map<String, String> map = stream.collect(Collectors.toMap(
                //把元素s映射为key:
                s -> s.substring(0, s.indexOf(":")),
                //把元素s映射为value
                s -> s.substring(s.indexOf(":") + 1)
        ));
        System.out.println(map);
    }


    @Test
    public void testGroup(){
        //创建一个字符串列表
        List<String> list = List.of("Apple" , "Banana" , "Blackberry" , "Coconut" , "Avocado" , "Cherry" , "Apricots");
        Map<String, List<String>> groups = list.stream()
                .collect(Collectors.groupingBy(s -> s.substring(0, 1), Collectors.toList()));
        System.out.println(groups);
    }



}
